#!/bin/bash

export PATH="$SNAP/usr/sbin:$SNAP/usr/bin:$SNAP/sbin:$SNAP/bin:$PATH"
export LD_LIBRARY_PATH="$LD_LIBRARY_PATH:$SNAP/lib:$SNAP/usr/lib:$SNAP/lib/x86_64-linux-gnu:$SNAP/usr/lib/x86_64-linux-gnu"
export LD_LIBRARY_PATH=$SNAP_LIBRARY_PATH:$LD_LIBRARY_PATH


source $SNAP/actions/common/utils.sh

KUBECTL="$SNAP/kubectl --kubeconfig=$SNAP/client.config"

# Arrray of what we query per addon
declare -A addon
addon[dns]="pod/coredns"
addon[rbac]="clusterrole.rbac.authorization.k8s.io/cluster-admin"
addon[dashboard]="pod/kubernetes-dashboard"
addon[ingress]="pod/nginx-ingress-microk8s-controller"
addon[storage]="pod/hostpath-provisioner"
addon[registry]="pod/registry"
addon[metrics-server]="pod/metrics-server"
addon[istio]="pod/istio"
addon[knative]="pod/knative"
addon[gpu]="daemonset.apps/nvidia-device-plugin-daemonset"
addon[prometheus]="pod/prometheus-k8s-0"
addon[fluentd]="daemonset.apps/fluentd-es-v2.2.0"
addon[jaeger]="pod/jaeger-operator"
addon[linkerd]="pod/linkerd-controller"


function show_help() {
    prog=$(basename -s.wrapper "$0" | tr - .)
    echo "Usage: $prog [--yaml] [--wait-ready [--timeout <seconds>]]"
    echo "Show the status of microks8. Use --yaml to get the response in yaml."
    echo "To wait for microk8s to become ready use the --wait-ready flag and provide a"
    echo "waiting timeout."
    echo ""
    echo "Example: $prog --wait-ready --timeout 60"
    echo ""
}

# Parse arguments. The variables yaml, wait_ready and timeout are filled.
function parse_args() {
    while [[ "$#" > 0 ]]
    do
        case "$1" in
            "--help") show_help ; exit 0 ;;
            "--yaml") yaml=1 ;;
            "--wait-ready") wait_ready=1 ;;
            "--timeout") timeout=$2 ; shift ;;
        esac
        shift
    done
}


# Wait for the timeout of microk8s to say it has a node. If timeout variable is set this method will not block.
function wait_for_ready() {
    start_timer="$(date +%s)"
    while ! ($KUBECTL get all --all-namespaces | grep -z "service/kubernetes") &> /dev/null
    do
        now="$(date +%s)"
        if ! [ -z $timeout ] && [[ "$now" > "$(($start_timer + $timeout))" ]] ; then
            break
        fi
        sleep 2
    done

    while ! ($KUBECTL get no | grep -z " Ready") &> /dev/null
    do
        now="$(date +%s)"
        if ! [ -z $timeout ] && [[ "$now" > "$(($start_timer + $timeout))" ]] ; then
            break
        fi
        sleep 2
    done
}


# Format the output based on the yaml variable. The status variable should be set.
function format_output() {
    if [ "$status" = "Running" ]
    then
      get_all="$($KUBECTL get all --all-namespaces 2>&1)"
      get_all="$get_all\n$($KUBECTL get clusterroles --show-kind --no-headers 2>&1)"
      for a in "${!addon[@]}"
      do
        if echo "$get_all" | grep "${addon[$a]}" &> /dev/null
        then
          addon["$a"]="enabled"
        else
          addon["$a"]="disabled"
        fi
      done
    fi

    if ! [ -z ${yaml} ]
    then
        if [ "$status" = "Running" ]
        then
            echo "microk8s:"
            echo "  running: true"
            echo "addons:"
            for a in "${!addon[@]}"
            do
              echo "  $a: ${addon[$a]}"
            done
            exit 0
        else
            echo "microk8s:"
            echo "  running: false"
            exit 1
        fi
    else
        if [ "$status" = "Running" ]
        then
            echo "microk8s is running"
            echo "addons:"
            for a in "${!addon[@]}"
            do
              echo "$a: ${addon[$a]}"
            done
            exit 0
        else
            echo "microk8s is not running. Use microk8s.inspect for a deeper inspection."
            exit 1
        fi
    fi
}


# See if we have timed out or we are running. Sets the status variable.
function check_ready() {
    status="Not running"
    if ($KUBECTL get all --all-namespaces | grep -z "service/kubernetes") &> /dev/null &&
       ($KUBECTL get no | grep -z " Ready") &> /dev/null
    then
        status="Running"
    fi
}


# Main flow #
parse_args "$@"
if ! [ -z ${wait_ready} ]
then
    wait_for_ready
fi
check_ready
format_output
